﻿using System.Diagnostics.Contracts;
using System.IO;
using System.Security.Cryptography;
using System.Web;

namespace TrackIT.Common
{
    public class PasswordManager
    {
        private static readonly byte[] Key = { 198, 146, 197, 192, 40, 231, 110, 243, 225, 210, 166, 243, 125, 242, 235, 114, 223, 44, 195, 169, 30, 133, 117, 178, 61, 132, 251, 124, 46, 217, 148, 208 };
        private static readonly byte[] IV = { 60, 185, 120, 244, 102, 224, 100, 200, 207, 95, 171, 127, 226, 165, 247, 50 };

        public static string DecryptFromBase64String(string token)
        {
            Contract.Requires(!string.IsNullOrEmpty(token));

            MemoryStream inputAsStream = null;
            CryptoStream decryptStream = null;
            BinaryReader reader = null;

            try
            {
                string retVal = string.Empty;
                RijndaelManaged rmCrypto = new RijndaelManaged();

                byte[] inputAsBytes = HttpServerUtility.UrlTokenDecode(token);
                if (inputAsBytes != null)
                {
                    inputAsStream = new MemoryStream(inputAsBytes);
                    decryptStream = new CryptoStream(inputAsStream, rmCrypto.CreateDecryptor(Key, IV),
                                                     CryptoStreamMode.Read);
                    reader = new BinaryReader(decryptStream);

                    retVal = reader.ReadString();
                }

                return retVal;
            }
            finally
            {
                if (reader != null)
                    reader.Close();

                if (decryptStream != null)
                    decryptStream.Dispose();

                if (inputAsStream != null)
                    inputAsStream.Dispose();
            }
        }

        public static string EncryptToBase64String(string packedValue)
        {
            Contract.Requires(!string.IsNullOrEmpty(packedValue));

            MemoryStream outputAsStream = null;
            CryptoStream encryptStream = null;
            BinaryWriter writer = null;

            try
            {
                RijndaelManaged rmCrypto = new RijndaelManaged();
                outputAsStream = new MemoryStream();
                encryptStream = new CryptoStream(outputAsStream, rmCrypto.CreateEncryptor(Key, IV), CryptoStreamMode.Write);
                writer = new BinaryWriter(encryptStream);

                writer.Write(packedValue);
                writer.Flush();
                encryptStream.Close();

                string retVal = HttpServerUtility.UrlTokenEncode(outputAsStream.ToArray());

                return retVal;
            }
            finally
            {
                if (writer != null)
                    writer.Close();

                if (encryptStream != null)
                    encryptStream.Dispose();

                if (outputAsStream != null)
                    outputAsStream.Dispose();
            }
        }
    }
}